/** @format */
import { useState, useRef, useEffect } from 'react'
import { Button, NavBar, Form, Input, Toast, InputRef } from 'antd-mobile'
import { useLocation, useNavigate } from 'react-router-dom'
import type { AxiosError } from 'axios'

import { LoginParams, Result } from '@/types/http'
import { useAppDispatch } from '@/store/hooks'
import { loginAsync } from '@/store/slice/login'
import { sendCodeApi } from '@/api/login'

import styles from './Login.module.scss'

// 倒计时hook
function useCountDown(startTimeLeft: number = 60) {
  // 定时器id ref
  const timerIdRef = useRef(-1)
  // 验证码倒计时
  let [timeLeft, setTimeLeft] = useState(0)
  useEffect(() => {
    if (timeLeft === 0) {
      clearInterval(timerIdRef.current)
    }
  }, [timeLeft])

  useEffect(() => {
    // 组件卸载时,关闭定时器
    return () => {
      clearInterval(timerIdRef.current)
    }
  }, [])

  const startCountDown = () => {
    // 设置初始时间
    setTimeLeft(startTimeLeft)
    // 开始倒计时
    timerIdRef.current = window.setInterval(() => {
      setTimeLeft((prev: number) => prev - 1)
    }, 1000)
  }
  return { timeLeft, startCountDown }
}
// 验证码hook
function useSendCode(startTimeLeft: number = 60) {
  // Form组件实例
  const [form] = Form.useForm()
  // 手机号文本框ref
  const inputRef = useRef<InputRef | null>(null)
  const { timeLeft, startCountDown } = useCountDown(startTimeLeft)
  // 发送验证码
  const onSendCode = async () => {
    try {
      if (timeLeft > 0) return
      // 验证手机号
      const { mobile } = await form.validateFields(['mobile'])
      // 请求验证码
      await sendCodeApi(mobile)

      startCountDown()
    } catch (e) {
      if (inputRef.current) {
        inputRef.current.focus()
      }
    }
  }
  return {
    form,
    inputRef,
    timeLeft,
    onSendCode
  }
}
// 登录hook
function useSubmit() {
  const dispatch = useAppDispatch()
  const location = useLocation()
  const navigate = useNavigate()
  // 按钮加载状态
  const [loading, setLoading] = useState(false)

  // 登录提交
  const onSubmit = async (values: LoginParams) => {
    try {
      // 开启加载
      setLoading(true)
      // 触发异步登录action
      await dispatch(loginAsync(values)).unwrap()
      // 成功提示
      Toast.show({
        content: '登录成功',
        duration: 700,
        afterClose: () => {
          navigate(location.state?.redirect || '/', { replace: true })
        }
      })
    } catch (e) {
      // 类型转换
      const error = e as AxiosError<Result<null>>
      // 失败提示
      Toast.show({
        content: error.response?.data.message || '登录出错',
        duration: 1300
      })
    } finally {
      // 关闭加载
      setLoading(false)
    }
  }
  return {
    loading,
    onSubmit
  }
}

const Login = () => {
  // 登录
  const { loading, onSubmit } = useSubmit()
  // 验证码
  const { timeLeft, inputRef, form, onSendCode } = useSendCode(60)
  return (
    <div className={styles.root}>
      <NavBar />
      <div className='login-form'>
        <h2 className='title'>账号登录</h2>

        <Form
          form={form}
          onFinish={onSubmit}
          initialValues={{
            mobile: '1352251353',
            code: '246810'
          }}>
          <Form.Item
            name='mobile'
            className='login-item'
            rules={[
              {
                required: true,
                message: '请填写手机号'
              },
              {
                pattern: /^1[3-9]\d{9}$/,
                message: '请填写正确格式'
              }
            ]}>
            <Input
              placeholder='请输入手机号'
              autoComplete='off'
              maxLength={11}
              ref={inputRef}
            />
          </Form.Item>

          <Form.Item
            className='login-item'
            name='code'
            rules={[
              { required: true, message: '请填写验证码' },
              {
                pattern: /^\d{6}$/,
                message: '请填写正确格式'
              }
            ]}
            extra={
              <span
                className='code-extra'
                onClick={onSendCode}>
                {timeLeft > 0 ? `${timeLeft}秒后重新获取` : '获取验证码'}
              </span>
            }>
            <Input
              placeholder='请输入验证码'
              autoComplete='off'
              maxLength={6}
            />
          </Form.Item>

          {/* noStyle 表示不提供 Form.Item 自带的样式 */}
          <Form.Item
            noStyle
            shouldUpdate>
            {() => (
              <Button
                block
                type='submit'
                color='primary'
                loading={loading}
                loadingText='登录中...'
                className='login-submit'
                disabled={
                  !form.isFieldsTouched(true) ||
                  !!form.getFieldsError().filter(({ errors }) => errors.length)
                    .length
                }>
                登 录
              </Button>
            )}
          </Form.Item>
        </Form>
      </div>
    </div>
  )
}

export default Login
